package billing

import (
	"context"
	"time"
)

// ========================================
// 计费拦截器系统 (Billing Interceptor System)
// 使用策略模式 + 责任链模式实现可插拔的流量控制和带宽限制
// ========================================

// PaymentType 付费类型
type PaymentType string

const (
	PaymentTypeCashier PaymentType = "cashier" // 收银台
	PaymentTypeQRCode  PaymentType = "qrcode"  // 二维码
)

// InterceptResult 拦截结果
type InterceptResult struct {
	// 是否可用
	Available bool `json:"available"`

	// 不可用原因（当Available=false时有效）
	Reason string `json:"reason,omitempty"`

	// 付费类型（当Available=false时有效）
	PaymentType PaymentType `json:"payment_type,omitempty"`

	// 付费URL地址（收银台URL或二维码URL，包含订单号）
	PaymentURL string `json:"payment_url,omitempty"`

	// 订单号（用于支付追踪）
	OrderID string `json:"order_id,omitempty"`

	// 额外信息（用于扩展）
	Extra map[string]interface{} `json:"extra,omitempty"`
}

// InterceptContext 拦截上下文（传递请求信息）
type InterceptContext struct {
	Ctx context.Context // Go上下文

	// 隧道信息
	TunnelID   string // 隧道ID
	UserID     string // 用户ID（从Tunnel中获取）
	RequestID  string // 请求ID
	Protocol   string // 协议类型（HTTP/TCP/QUIC）
	RemoteAddr string // 客户端地址

	// 流量信息
	RequestSize  int64 // 请求大小（字节）
	ResponseSize int64 // 响应大小（字节，可能在请求处理后才知道）

	// 带宽信息
	CurrentBandwidth int64     // 当前带宽使用（字节/秒）
	RequestTime      time.Time // 请求时间

	// HTTP特定信息（可选）
	HTTPMethod    string            // HTTP方法
	HTTPPath      string            // HTTP路径
	HTTPHeaders   map[string]string // HTTP头部
	IsJSONRequest bool              // 是否是JSON请求（根据Content-Type判断）
	AcceptHTML    bool              // 是否接受HTML响应（根据Accept判断）
}

// BillingInterceptor 计费拦截器接口
// 使用责任链模式，每个拦截器可以决定是否放行或拦截
type BillingInterceptor interface {
	// Name 拦截器名称（用于日志和调试）
	Name() string

	// Intercept 拦截方法
	// 返回：
	//   - *InterceptResult: 拦截结果（nil表示放行，继续下一个拦截器）
	//   - error: 错误（系统错误，非业务错误）
	Intercept(ctx *InterceptContext) (*InterceptResult, error)

	// Priority 优先级（数字越小越先执行）
	// 推荐：流量配额=10, 带宽限制=20, 自定义=30+
	Priority() int
}

// InterceptorChain 拦截器链
type InterceptorChain struct {
	interceptors []BillingInterceptor
}

// NewInterceptorChain 创建拦截器链
func NewInterceptorChain() *InterceptorChain {
	return &InterceptorChain{
		interceptors: make([]BillingInterceptor, 0),
	}
}

// AddInterceptor 添加拦截器（自动按优先级排序）
func (chain *InterceptorChain) AddInterceptor(interceptor BillingInterceptor) {
	chain.interceptors = append(chain.interceptors, interceptor)

	// 按优先级排序（冒泡排序，简单有效）
	for i := 0; i < len(chain.interceptors)-1; i++ {
		for j := 0; j < len(chain.interceptors)-i-1; j++ {
			if chain.interceptors[j].Priority() > chain.interceptors[j+1].Priority() {
				chain.interceptors[j], chain.interceptors[j+1] = chain.interceptors[j+1], chain.interceptors[j]
			}
		}
	}
}

// Execute 执行拦截器链
// 返回第一个拦截的结果，如果所有拦截器都放行则返回nil（表示可用）
func (chain *InterceptorChain) Execute(ctx *InterceptContext) (*InterceptResult, error) {
	for _, interceptor := range chain.interceptors {
		result, err := interceptor.Intercept(ctx)
		if err != nil {
			return nil, err
		}

		// 如果拦截器返回了结果（不可用），则立即返回
		if result != nil && !result.Available {
			return result, nil
		}
	}

	// 所有拦截器都放行，返回可用结果
	return &InterceptResult{
		Available: true,
	}, nil
}

// Clear 清空拦截器链
func (chain *InterceptorChain) Clear() {
	chain.interceptors = make([]BillingInterceptor, 0)
}

// Count 拦截器数量
func (chain *InterceptorChain) Count() int {
	return len(chain.interceptors)
}
